package controler;


import java.util.Vector;
import Dub.DubConjunto;
import Dub.DubDeTemporada;
import Dub.DubMaterial;
import Dub.DubPrenda;
import Dub.DubProveedor;
import Dub.DubSinTemporada;
import model.*;



public class SistemaIndumentaria {
	private static SistemaIndumentaria instancia = null;
	private Vector<Material> materiales;
	private Vector<Proveedor> proveedores;
	private Vector<Prenda> prendas;
	private Vector<Conjunto> conjuntos;
	private Vector<OrdenCompra> ordenes;
	private Venta ventaActual;
	
	public SistemaIndumentaria(){
		this.materiales = new Vector<Material>();
		this.proveedores = new Vector<Proveedor>();
		this.prendas = new Vector<Prenda>();
		this.conjuntos = new Vector<Conjunto>();
		this.ordenes = new Vector<OrdenCompra>();
	}
	

	public static SistemaIndumentaria getInstancia() {
		if (instancia == null) {
			instancia = new SistemaIndumentaria();
		}
		return instancia;
	}


	public Material buscarMaterial(int codigo){
		
		if(this.materiales!=null)
		{
			for(int i=0; i<this.materiales.size(); i++){
				if(materiales.elementAt(i).getCodigo()==codigo)
					return materiales.elementAt(i);
			}
		}		
		Material m = persistence.APMaterial.buscarMaterial(codigo);
		if(m!=null)
			{
				materiales.add(m);
				return m;
			}
		
		return null;		
	}
	

	public Material buscarMaterial(String nombre){
		if(this.materiales!=null)
		{
			for(int i=0; i<this.materiales.size(); i++){
				if(materiales.elementAt(i).equals(nombre))
					return materiales.elementAt(i);
			}
		}
		Material m = persistence.APMaterial.buscarMaterialNombre(nombre);
		if(m!=null)
			{
				materiales.add(m);
				return m;
			}
		
		return null;	
	}
	

	public void agregarProveedor(int idProveedor,String cuit, String direccion, String telefono,String razonSocial) {
		Proveedor prov = new Proveedor(idProveedor, cuit,direccion,telefono,razonSocial);
		proveedores.add(prov);
		persistence.APProveedor.insertarProveedor(prov);
	}


	public void modificarProveedor(int idProveedor,String cuit, String direccion, String telefono,String razonSocial) {
		Proveedor proveedor = buscarProveedor(idProveedor);
		if (proveedor != null) {
			persistence.APProveedor.modificarProveedor(proveedor);
		}
	}

	public void removerProveedor(int idProveedor) {
		Proveedor proveedor = buscarProveedor(idProveedor);
		if (proveedor != null) {
			proveedores.remove(proveedor);
		}
		persistence.APProveedor.borrarProveedor(idProveedor);
	}


	public Proveedor buscarProveedor(int idProveedor) {
		if(this.proveedores!=null)
		{
		for (int i = 0; i < proveedores.size(); i++) {
			if (proveedores.elementAt(i).getIdProveedor() == idProveedor) {
				return proveedores.elementAt(i);
			}
		}
		}
			Proveedor p = persistence.APProveedor.buscarProveedor(idProveedor);
			if (p != null) {
				proveedores.add(p);
			}
	
		return p;
	}
	
	public Proveedor buscarProveedor(String razonSocial) {
		if(this.proveedores!=null)
		{
		for (int i = 0; i < proveedores.size(); i++) {
			if (proveedores.elementAt(i).getRazonSocial().equalsIgnoreCase(razonSocial)) {
				return proveedores.elementAt(i);
			}
		}
		}
			Proveedor p = persistence.APProveedor.buscarProveedor(razonSocial);
			if (p != null) {
				proveedores.add(p);
				return p;
			}
	
		return null;
	}

	public boolean existeProveedor(int idProveedor) {
		return buscarProveedor(idProveedor) != null;
	}

	public DubProveedor buscarDubProveedor(int idProveedor) {
		
		@SuppressWarnings("unused")
		DubProveedor dubp = null;
		
		for (int i = 0; i < proveedores.size(); i++) {
			if (proveedores.elementAt(i).getIdProveedor() == idProveedor)
				return dubp = new DubProveedor(proveedores.elementAt(i));
		}
		Proveedor p = persistence.APProveedor.buscarProveedor(idProveedor);
		if (p != null) {
			proveedores.add(p);
		}
		return dubp = new DubProveedor(p);
	}
		
	public boolean agregarMaterial(int codigo, String nombre,int puntoPedido, float costo, int stock, int idProveedor) {
		if((buscarMaterial(codigo)==null) && (buscarMaterial(nombre)==null) && (buscarProveedor(idProveedor)!=null)){
			Material mat = new Material(codigo, nombre, puntoPedido, costo, stock,idProveedor);
			materiales.add(mat);
			persistence.APMaterial.insertarMaterial(mat);
			return true;
		}
		return false;
	}

	public void modificarMaterial(int codigo, String nombre, int puntoPedido, float costo, int stock, int idProveedor) {
		Proveedor proveedor = buscarProveedor(idProveedor);
		if (proveedor != null) {
			Material material = buscarMaterial(codigo);
			if (material != null) {
				material.setNombre(nombre);
				material.setPuntoPedido(puntoPedido);
				material.setCosto(costo);
				material.setStock(stock);
				material.setIdProveedor(idProveedor);
				persistence.APMaterial.modificarMaterial(material);				
			}	
		}
	}


	public boolean buscarMaterialEnPrendasActivas(int codigo)
	{//recore la lista de prendas, le puse estado 1 = ACTIVAS y si alguna le existe el material avisa que existe
		if(this.prendas!=null)
		{
			for (int i = 0; i < prendas.size(); i++) {
				if (prendas.elementAt(i).getEstado()==1)
				{
					if (prendas.elementAt(i).existeMaterialEnPrenda(codigo))
					{
						return true;
					}
				}			
			}
		}
		Vector <Prenda> pren = persistence.APPrenda.getPrendasActivos();
		if(pren.size()>0) return false;
		else{
			this.prendas.addAll(pren);
			for (int i = 0; i < pren.size(); i++) {
				
				if (pren.elementAt(i).existeMaterialEnPrenda(codigo))
				{
					return true;
				}
			}
		}
		return false;
	}

	public boolean buscarPrendaEnConjuntosActivos(int prendaId)
	{//recore la lista de prendas, le puse estado 1 = ACTIVAS y si alguna le existe el material avisa que existe
		if(this.conjuntos!=null)
		{
			for (int i = 0; i < conjuntos.size(); i++) {
				if (conjuntos.elementAt(i).getEstado()==1)
				{
					if (conjuntos.elementAt(i).buscarPrenda(prendaId)!=null)
					{
						return true;
					}
				}			
			}
		}
		Vector <Conjunto> conjs = persistence.APConjunto_Prenda.buscarPrendaEnConjuntosActivos(prendaId);
		if(conjs.size()>0)
			{
				conjuntos.addAll(conjs);
				return true;
			}
		return false;
	}

	public void removerMaterial(int codigo) {
		Material material = buscarMaterial(codigo);
		if (material != null) {
			if(!buscarMaterialEnPrendasActivas(codigo))
			{
				materiales.remove(material);
				persistence.APMaterial.borrarMaterial(codigo);
			}
		}
	}
	
	
	public boolean existeMaterial(int materialId) {
		return buscarMaterial(materialId) != null;
	}


	public DubMaterial buscarDubMaterial(int codigo) {
		DubMaterial dubm = null;
		
		for (int i = 0; i < materiales.size(); i++) {
			if (materiales.elementAt(i).getCodigo() == codigo){
				 dubm = new DubMaterial(materiales.elementAt(i));
				return dubm;
			}
		}
		Material m= persistence.APMaterial.buscarMaterial(codigo);
		if (m != null) {
			materiales.add(m);
		}
		return dubm = new DubMaterial(m);
	}
	
	public DubConjunto buscarDubConjunto(int codigo) {
		DubConjunto dubm = null;
		
		for (int i = 0; i < conjuntos.size(); i++) {
			if (conjuntos.elementAt(i).getCodigo() == codigo){
				 dubm = new DubConjunto(conjuntos.elementAt(i));
				return dubm;
			}
		}
		Conjunto m= persistence.APConjunto.buscarAPConjunto(codigo);
		if (m != null) {
			conjuntos.add(m);
			dubm = new DubConjunto(m);
		}
		 return dubm;
	}



	public boolean altaPrendaTemporada(int prendaId, String nombre, String estacionAnio)
	{
		 if((buscarPrenda(prendaId)==null) && (buscarPrenda(nombre)==null)){
				DeTemporada prendaTemporada = new DeTemporada(nombre,prendaId, estacionAnio);	
				prendas.add(prendaTemporada);
				return true;	
		 }
		 return false;
	}
 
	public boolean altaPrendaSinTemporada(int prendaId, String nombre)
	{
		 if((buscarPrenda(prendaId)==null) && (buscarPrenda(nombre)==null)){
				SinTemporada prendaSinTemporada = new SinTemporada(prendaId,nombre);	
				prendas.add(prendaSinTemporada);
				return true;	
		 }
	 return false;
	}

	public Prenda buscarPrenda(int prendaId){
		if(this.prendas!=null)
		{
			for(int i=0; i<this.prendas.size(); i++){
				if(prendas.elementAt(i).getCodigo()==prendaId)
					return prendas.elementAt(i);
			}
		}
		Prenda p = persistence.APPrenda.buscarPrenda(prendaId);
		if (p != null) {
			prendas.add(p);
			return p;
		}		
		return null;		
	}

	public Prenda buscarPrenda(String nombre){
		if(this.prendas!=null)
		{
			for(int i=0; i<this.prendas.size(); i++){
				if(prendas.elementAt(i).equals(nombre))
					return prendas.elementAt(i);
				}
		}
		Prenda p = persistence.APPrenda.buscarPrenda(nombre);
		if (p != null) {
			prendas.add(p);
			return p;
		}						
		return null;
	}
	
	public boolean agregarMaterialAPrenda(int materialId, int prendaId, int cantidad)
	{
		Material mat = buscarMaterial(materialId);
		if(mat!=null)
		{			
			return buscarPrenda(prendaId).agregarMaterial(mat, cantidad);
		}
		return false;
	}

	public float calcularPrecioPrenda(int prendaId)
	{
		return buscarPrenda(prendaId).calcularPrecioRopa();
	}

	public void confirmarPrendaTemporada(int prendaId)
	{
		Prenda pren = buscarPrenda(prendaId);
		persistence.APDeTemporada.altaPrendaTemporada((DeTemporada)pren);
		persistence.APMaterial_Prenda.agregarMaterialesAPrenda(pren);
	}

	public void confirmarPrendaSinTemporada(int prendaId)
	{
		Prenda pren = buscarPrenda(prendaId);
		persistence.APSinTemporada.insertarAPSinTemporada((SinTemporada)pren);
		persistence.APMaterial_Prenda.agregarMaterialesAPrenda(pren);
	}

	public boolean altaConjunto(int conjuntoId, String nombre, float descuento)
	{
		if (buscarConjunto(conjuntoId)==null)
		{
			Conjunto conjunto = new Conjunto(conjuntoId, nombre, descuento);
			conjuntos.add(conjunto);
			return true;
		}
		return false;
	}

	public Conjunto buscarConjunto(int conjuntoId) {
		if(this.conjuntos!=null)
		{
			for(int i=0; i<conjuntos.size();i++)
			{
				if(conjuntos.elementAt(i).getCodigo()==conjuntoId)
				{
					return conjuntos.elementAt(i);
				}
			}
		}		
		Conjunto conj = persistence.APConjunto.buscarAPConjunto(conjuntoId);
		if (conj!=null)
			this.conjuntos.add(conj);
		return conj;
	}
	
	public Conjunto buscarConjunto(String conjuntoNombre) {
		if(this.conjuntos!=null)
		{
			for(int i=0; i<conjuntos.size();i++)
			{
				if(conjuntos.elementAt(i).getNombre().equalsIgnoreCase(conjuntoNombre))
				{
					return conjuntos.elementAt(i);
				}
			}
		}		
		Conjunto conj = persistence.APConjunto.buscarAPConjunto(conjuntoNombre);
		if (conj!=null)
			this.conjuntos.add(conj);
		return conj;
	}
	
	public boolean agregarPrendaAConjunto(int conjuntoId, int prendaId)
	{
		Prenda pren =buscarPrenda(prendaId);
		if(pren!=null)
		{
			return buscarConjunto(conjuntoId).agregarPrendaAConjunto(pren);
		}
		return false;
	}

	public float calcularPrecioConjunto(int conjuntoId)
	{
		return buscarConjunto(conjuntoId).calcularPrecioRopa();
	}
	
	public void confirmarConjunto(int conjuntoId)
	{
		Conjunto con = buscarConjunto(conjuntoId);
		conjuntos.add(con);
		persistence.APConjunto.insertarAPConjunto(con);
		persistence.APConjunto_Prenda.insertarAPConjunto_Prenda(con);
	}

	public void removerConjunto(int conjuntoId)
	{
		Conjunto con = buscarConjunto(conjuntoId);
		if (con!=null)
		{
			conjuntos.remove(con);
			persistence.APConjunto.borrarAPConjunto(con.getCodigo());		
		}
	}

	public boolean removerPrenda(int prendaId)
	{
		Prenda pren = buscarPrenda(prendaId);
		if (pren!=null)
		{
			if(!buscarPrendaEnConjuntosActivos(prendaId))
			{
				prendas.remove(pren);
				persistence.APPrenda.borrarAPPrenda(pren.getCodigo());
				return true;
			}
		}
		return false;
	}
	
	public boolean modificarConjunto(int conjuntoId, String nombre, float descuento)
	{
		Conjunto con = buscarConjunto(conjuntoId);
		
		if (con != null)
		{
			con.setNombre(nombre);
			con.setDescuento(descuento);
			persistence.APConjunto.modificarAPConjunto(con);			
			return true;
		}
		return false;
	}
	

	public boolean modificarPrendaConTemporada(int prendaId, String nombre, String estacionAnio)
	{
		DeTemporada pren = (DeTemporada)buscarPrenda(prendaId);
		if (pren!=null)
		{
			pren.setNombre(nombre);
			pren.setEstacionAnio(estacionAnio);		
			persistence.APDeTemporada.modificarAPConTemporada(pren);
			
			return true;
		}		
		
		return false;
	}
	

	public Vector<String> buscarMaterialesPtoPedido() {
		
		Vector<Material> materiales = persistence.APMaterial.buscarMaterialesPuntoDePedido();
		Vector<String> materialesNombres = new Vector<String>();
		
		if(materiales!=null){
			for(int i= 0; i<materiales.size(); i++){
				materialesNombres.add(materiales.elementAt(i).getNombre());
			}
			return materialesNombres;
		}
		return null;
	}
	
	
	public Vector<String> buscarRopaDisponible() {
		
		Vector<Ropa> ropas = persistence.APRopa.getRopaActiva();
		Vector<String> ropaNombres = new Vector<String>();
		if(ropas!=null){
			for(int i= 0; i<ropas.size(); i++){
				
				ropaNombres.add(ropas.elementAt(i).getNombre());
			}

			return ropaNombres;
		}
		return null;
	}
	

	public OrdenCompra buscarOrdenActiva(int idProveedor){
		if(ordenes!=null){
			for (int i = 0; i<ordenes.size(); i++){
				if((ordenes.elementAt(i).getProveedor().getIdProveedor()==idProveedor)&&(ordenes.elementAt(i).getEstado().equalsIgnoreCase("Pendiente de entrega"))){
					return ordenes.elementAt(i);
				}				
			}
		}
		OrdenCompra orden = persistence.APOrdenDeCompra.buscarOrdenActiva(idProveedor);
		if(orden!=null){
			ordenes.add(orden);
		}
		return orden;
	}
	
	public OrdenCompra buscarOrdenEsperandoEntrega(int idProveedor){
		if(ordenes!=null){
			for (int i = 0; i<ordenes.size(); i++){
				if((ordenes.elementAt(i).getProveedor().getIdProveedor()==idProveedor)&&(ordenes.elementAt(i).getEstado().equalsIgnoreCase("Esperando entrega"))){
					return ordenes.elementAt(i);
				}				
			}
		}
		OrdenCompra orden = persistence.APOrdenDeCompra.buscarOrdenEsperandoEntrega(idProveedor);
		if(orden!=null){
			ordenes.add(orden);
		}
		return orden;
	}


	public boolean generarOrdenDeCompra(String nombreMaterial, int cant) {
		Material mat = buscarMaterial(nombreMaterial);
		OrdenCompra orden = buscarOrdenActiva(mat.getIdProveedor());		
		if(orden!=null){
			persistence.APOrdenDeCompra.agregarItem(orden.agregarItem(mat, cant));
		}
		else{
			orden =new OrdenCompra(buscarProveedor(mat.getIdProveedor()));
			ordenes.add(orden);
			persistence.APOrdenDeCompra.crearOrden(orden);
			persistence.APOrdenDeCompra.agregarItem(orden.agregarItem(mat, cant));
		}
		return true;
	}



	public Vector<String> buscarProveedoresOrdenDeCompraActiva() {
		Vector<Proveedor> prove = persistence.APProveedor.proveedoresConOrdenActivas();
		Vector<String> nombresProveedores = new Vector<String>();
		if(prove!=null){
			for(int i = 0; i<prove.size(); i++){
					nombresProveedores.add(prove.elementAt(i).getRazonSocial());
				}
			
		}
		return nombresProveedores;
	}
	
	public Vector<String> buscarProveedoresOrdenDeCompraEsperandoEntrega() {
		Vector<Proveedor> prove = persistence.APProveedor.buscarProveedoresOrdenDeCompraEsperandoEntrega();
		Vector<String> nombresProveedores = new Vector<String>();
		if(prove!=null){
			for(int i = 0; i<prove.size(); i++){
					nombresProveedores.add(prove.elementAt(i).getRazonSocial());
				}
			
		}
		return nombresProveedores;
	}


	public void enviarOrdenDeCompra(String descProveedor) {
			
		buscarOrdenActiva(buscarProveedor(descProveedor).getIdProveedor()).enviarOC();
		
	}


	public DubPrenda buscarDubPrenda(int codigo) {
		DubPrenda dubm = null;	
		for (int i = 0; i < prendas.size(); i++) {
			if (prendas.elementAt(i).getCodigo() == codigo){
				 if(prendas.elementAt(i) instanceof DeTemporada )
				dubm = new DubDeTemporada((DeTemporada)prendas.elementAt(i));
				 else
				dubm = new DubSinTemporada((SinTemporada)prendas.elementAt(i));			
					return dubm;
			}	
		}
		Prenda p= persistence.APPrenda.buscarPrenda(codigo);
		if (p != null) {
			prendas.add(p);
		}
		 if(p instanceof DeTemporada )
			dubm = new DubDeTemporada((DeTemporada)p);
		 else
			dubm = new DubSinTemporada((SinTemporada)p);			
			return dubm;		
	}



	public boolean modificarPrendaSinTemporada(DubSinTemporada p) {
		SinTemporada pren = (SinTemporada)buscarPrenda(p.getCodigo());
		if (pren!=null)
		{
			pren.setNombre(p.getNombre());			
			persistence.APSinTemporada.modificarAPSinTemporada(pren);			
			return true;
		}		
		return false;
	}


	public boolean modificarPrendaConTemporada(DubDeTemporada p) {
		DeTemporada pren = (DeTemporada)buscarPrenda(p.getCodigo());
		if (pren!=null)
		{
			pren.setNombre(p.getNombre());
			pren.setEstacionAnio(p.getEstacionAnio());
			persistence.APDeTemporada.modificarAPConTemporada(pren);			
			return true;
		}		
		return false;
	}

	public boolean modificarConjunto(DubConjunto c) {
		Conjunto con = (Conjunto)buscarConjunto(c.getCodigo());
		if (con!=null)
		{
			con.setNombre(c.getNombre());
			persistence.APConjunto.modificarAPConjunto(con);
				
			return true;
		}		
		return false;
	}
	
	public boolean generarFactura(int nroVenta, String nombre, int cant) {
		boolean itemCreado = false;	
			if(ventaActual==null){
				ventaActual = new Venta(nroVenta);
			}
		
			Prenda p = buscarPrenda(nombre);

			Conjunto c = buscarConjunto(nombre);
			if(p!=null){
				if(hayStockParaPrenda(p,cant)){
					ventaActual.agregarItem(p, cant);
					itemCreado = true;
				}
			}
			else{
				boolean hayStockParaConjunto = true;
				int i = 0;
				while ((i<c.getPrendas().size())&&(hayStockParaConjunto)){
					if(!hayStockParaPrenda(c.getPrendas().elementAt(i),cant)){
						hayStockParaConjunto = false;
					}
					i++;
				}
				if(hayStockParaConjunto){
					ventaActual.agregarItem(c, cant);
					itemCreado = true;
				}
			}
			return itemCreado;
	}



	public void cerrarOrdenDeCompra(String descProveedor) {
		buscarOrdenEsperandoEntrega(buscarProveedor(descProveedor).getIdProveedor()).cerrarOC();
		
	}
	
	public boolean hayStockParaPrenda(Prenda p, int cant){
	boolean hayStock = true;
	int i = 0;
		while(i<p.getItemMateriales().size() && hayStock){
		ItemMaterial m= p.getItemMateriales().elementAt(i);
		if(m.getCantidad()*cant > buscarMaterial(m.getMaterial().getNombre()).getStock()){
			hayStock = false;
			}
		i++;
		}
	return hayStock;
	}


	public void confirmarVenta() {
		persistence.APVenta.insertarVenta(ventaActual);
		actualizarStock(ventaActual);
		ventaActual = null;
		
		
	}


		private void actualizarStock(Venta ventaActual) {	
				for(int i = 0; i<ventaActual.getItems().size(); i++){				
					int codigo = ventaActual.getItems().elementAt(i).getRopa().getCodigo();
					Prenda p = buscarPrenda(codigo);				
					if (p != null) {
						actualizarStockMaterialesEnPrendas(p,ventaActual.getItems().elementAt(i));
					}
					else{
					Conjunto c = buscarConjunto(codigo);
					for(int j = 0; j<c.getPrendas().size();j++){
						actualizarStockMaterialesEnPrendas(c.getPrendas().elementAt(j), ventaActual.getItems().elementAt(i));					
					}
				}
					
			}
		}	
			


		private void actualizarStockMaterialesEnPrendas(Prenda p, ItemVenta item) {
			for (int j = 0; j < p.getItemMateriales().size(); j++) {
				p.getItemMateriales().elementAt(j).getMaterial().setStock(p.getItemMateriales().elementAt(j).getMaterial().getStock() -
						item.getCantidad() * p.getItemMateriales().elementAt(j).getCantidad()
				);
				persistence.APMaterial.modificarMaterial(p.getItemMateriales().elementAt(j).getMaterial());
			}
		}


		public boolean existeFactura(int parseInt) {
			return persistence.APVenta.buscarVenta(parseInt);
		}


		
	
}